package com.fowo.api.common.messages;

import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;

import java.text.MessageFormat;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 国际化工具类
 */
@Component
public class MessageUtils {
    private static MessageSource messageSource;

    public MessageUtils(MessageSource messageSource) {
        MessageUtils.messageSource = messageSource;
    }

    /**
     * 获取国际化键对应的消息
     * @param msgKey 国际化消息键
     * @param args 参数
     */
    public static String get(String msgKey, Object...args) {
        try {
            return messageSource.getMessage(msgKey, args, LocaleContextHolder.getLocale());
        } catch (Exception e) {
            return msgKey;
        }
    }

    /**
     * 获取指定语言的国际化键对应的消息
     * @param locale 语言
     * @param msgKey 国际化消息键
     * @param args 参数
     */
    public static String getWithLocale(String locale, String msgKey, Object...args) {
        try {
            return messageSource.getMessage(msgKey, args, new Locale(locale.replaceAll("-", "_")));
        } catch (Exception e) {
            return msgKey;
        }
    }

    /**
     * 获取国际化键对应的消息
     * @param msgKey 国际化消息键
     * @param defaultMessage 国际化消息键未找到时的默认消息
     * @param args 参数
     */
    public static String getOrDefault(String msgKey, String defaultMessage, Object...args) {
        try {
            return messageSource.getMessage(msgKey, args, LocaleContextHolder.getLocale());
        } catch (NoSuchMessageException e) {
            return MessageFormat.format(defaultMessage, args);
        } catch (Exception e) {
            return msgKey;
        }
    }

    private static final Pattern formatPattern = Pattern.compile("\\{([a-z][.[\\s\\S]]*)}", Pattern.CASE_INSENSITIVE);

    /**
     * 格式化消息中的 {msgKey(国际化消息键)} 填充，然后使用 MessageFormat 返回
     * @param message 消息
     * @param args 消息参数
     */
    public static String format(String message, Object...args) {
        final Matcher matcher = formatPattern.matcher(message);
        StringBuilder localSb = new StringBuilder();
        while(matcher.find()) {
            String msgKey = matcher.group(1);
            matcher.appendReplacement(localSb, get(msgKey));
        }
        matcher.appendTail(localSb);
        String localMessage = localSb.toString();
        return MessageFormat.format(localMessage, args);
    }
}
